﻿using Furion.Reflection;
using Furion.Reflection.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Application
{
    public class LogDispatchProxy : AspectDispatchProxy, IDispatchProxy //(AOP注册拦截), IGlobalDispatchProxy(全局AOP拦截)，这样就会拦截所有的Service，当然也可以通过给特定类贴 [SuppressProxy] 跳过全局拦截操作
    {
        /// <summary>
        /// 当前服务实例
        /// </summary>
        public object Target { get ; set ; }

        /// <summary>
        /// 服务提供器，可以用来解析服务，如：Services.GetService()
        /// </summary>
        public IServiceProvider Services { get; set; }

        /// <summary>
        /// 拦截方法
        /// </summary>
        /// <param name="method"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override object Invoke(MethodInfo method, object[] args)
        {
            Console.WriteLine("SayHello 方法被调用了");

            var result = method.Invoke(Target, args);

            Console.WriteLine("SayHello 方法返回值：" + result);

            return result;
        }

        /// <summary>
        /// 异步无返回值
        /// </summary>
        /// <param name="method"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override async Task InvokeAsync(MethodInfo method, object[] args)
        {
            Console.WriteLine("SayHello 方法被调用了");

            var task = method.Invoke(Target, args) as Task;
            await task;

            Console.WriteLine("SayHello 方法调用完成");
        }

        /// <summary>
        /// 异步带返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="method"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public override async Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args)
        {
            Console.WriteLine("SayHello 方法被调用了");

            var taskT = method.Invoke(Target, args) as Task<T>;
            var result = await taskT;

            Console.WriteLine("SayHello 方法返回值：" + result);

            return result;
        }

        // 获取特性
        // 如果需要获取方法的特性，只需要通过
        // method.GetActualCustomAttribute<TArrbute>()即可。
        // 所有获取真实的特性统一采用method.GetActual....()方法开头

        // 拦截优先级
        // [SuppressProxy] > [Injection(Proxy = typeof(LogDispatchProxy))] > 全局拦截
    }
}
